package solutions.ferpa.ztest.ent;

import java.sql.*;
import java.util.ArrayList;
import br.com.telescope.adsrt.dom.*;
import br.com.telescope.adsrt.lib.*;
import br.com.telescope.t2.exception.Severity;

/**
 * API de persistência de dados da entidade TIPO_MODELO_HIDROMETRO
 * @author Gerado pelo Telescope
 */
public class EntTipoModeloHidrometro extends Entity {
    
    public final static String ENTITY_NAME = "ZTEST.TIPO_MODELO_HIDROMETRO";
    public final static String TABLE_NAME = "TIPO_MODELO_HIDROMETRO";
    
    // <editor-fold defaultstate="collapsed" desc="Contrutores e inicializacao">
    /**
     * Construtores
     */
    public EntTipoModeloHidrometro() {
        super();
        initialize();
    }
    
    public EntTipoModeloHidrometro(BaseRuntime ctx) {
        super();
        initialize(ctx);
    }
    
    @Override
    public String getPrimaryKeyColumn() {
        return "ID";
    }
    
    @Override
    public void initialize(BaseRuntime ctx) {
        super.initialize(ctx);
        initialize();
    }
    
    public void initialize() {
        aId = new DomId(this,"ID", "Id"); 
        aId.setRequired(true);
        oId = new DomId();
        aCodigo = new DomText(this,"CODIGO", "Código do tipo de modelo"); 
        aCodigo.setRequired(true);
        aCodigo.setSize(64);
        oCodigo = new DomText();
        aNome = new DomText(this,"NOME", "Nome do tipo de modelo"); 
        aNome.setRequired(true);
        aNome.setSize(128);
        oNome = new DomText();
        aVazaoNominal = new DomDouble(this,"VAZAO_NOMINAL", "Vazão nominal (m3/h)"); 
        aVazaoNominal.setRequired(true);
        oVazaoNominal = new DomDouble();
        aPrefixoNumeroSerie = new DomUpper(this,"PREFIXO_NUMERO_SERIE", "Prefixo para número de série"); 
        aPrefixoNumeroSerie.setRequired(true);
        oPrefixoNumeroSerie = new DomUpper();
        aDescricao = new DomTextLong(this,"DESCRICAO", "Descrição"); 
        aDescricao.setSize(512);
        oDescricao = new DomTextLong();
        aPrefixoModelo = new DomUpper(this,"PREFIXO_MODELO", "Prefixo do modelo"); 
        aPrefixoModelo.setRequired(true);
        oPrefixoModelo = new DomUpper();
        aProximaSequenciaProduto = new DomInteger(this,"PROXIMA_SEQUENCIA_PRODUTO", "Próxima sequência produto"); 
        aProximaSequenciaProduto.setRequired(true);
        aProximaSequenciaProduto.setDefaultValue("1");
        oProximaSequenciaProduto = new DomInteger();
        ressetModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributos da entidade">
    
    // Id
    private DomId aId;
    private DomId oId;
    
    // Código do tipo de modelo
    private DomText aCodigo;
    private DomText oCodigo;
    
    // Nome do tipo de modelo
    private DomText aNome;
    private DomText oNome;
    
    // Vazão nominal (m3/h)
    private DomDouble aVazaoNominal;
    private DomDouble oVazaoNominal;
    
    // Prefixo para número de série
    private DomUpper aPrefixoNumeroSerie;
    private DomUpper oPrefixoNumeroSerie;
    
    // Descrição
    private DomTextLong aDescricao;
    private DomTextLong oDescricao;
    
    // Prefixo do modelo
    private DomUpper aPrefixoModelo;
    private DomUpper oPrefixoModelo;
    
    // Próxima sequência produto
    private DomInteger aProximaSequenciaProduto;
    private DomInteger oProximaSequenciaProduto;
    
    // <editor-fold defaultstate="collapsed" desc="Atributo ID">
    
    public EntTipoModeloHidrometro id(Long value) {
        setId(value);
        return this;
    }
    
    public void setId(DomId value) {
        if (value == null || value.isNull()) {
            nullifyId();
        } else {
            aId.setValue(value.getValue());
            if (aId.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setId(String value) {
        if (value == null) {
            nullifyId();
        } else {
            aId.setValue(value);
            if (aId.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setId(Long value) {
        aId.setValue(value);
        if (aId.isModified()) {
            setModified(true);
        }
    }
    
    public void setId(Object value) {
        aId.setValue(value);
        if (aId.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyId() {
        if (!aId.isNull()) {
            aId.setNull(true);
            setModified(true);
        }
    }
    
    public DomId getId() {
        return aId;
    }
    
    public DomId oldId() {
        return oId;
    }
    
    public Long valueOfId() {
        return aId.getValue();
    }
    
    public boolean isIdModified() {
        return aId.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo CODIGO">
    
    public EntTipoModeloHidrometro codigo(String value) {
        setCodigo(value);
        return this;
    }
    
    public void setCodigo(DomText value) {
        if (value == null || value.isNull()) {
            nullifyCodigo();
        } else {
            aCodigo.setValue(value.getValue());
            if (aCodigo.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setCodigo(String value) {
        if (value == null) {
            nullifyCodigo();
        } else {
            aCodigo.setValue(value);
            if (aCodigo.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setCodigo(Object value) {
        aCodigo.setValue(value);
        if (aCodigo.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyCodigo() {
        if (!aCodigo.isNull()) {
            aCodigo.setNull(true);
            setModified(true);
        }
    }
    
    public DomText getCodigo() {
        return aCodigo;
    }
    
    public DomText oldCodigo() {
        return oCodigo;
    }
    
    public String valueOfCodigo() {
        return aCodigo.getValue();
    }
    
    public boolean isCodigoModified() {
        return aCodigo.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo NOME">
    
    public EntTipoModeloHidrometro nome(String value) {
        setNome(value);
        return this;
    }
    
    public void setNome(DomText value) {
        if (value == null || value.isNull()) {
            nullifyNome();
        } else {
            aNome.setValue(value.getValue());
            if (aNome.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setNome(String value) {
        if (value == null) {
            nullifyNome();
        } else {
            aNome.setValue(value);
            if (aNome.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setNome(Object value) {
        aNome.setValue(value);
        if (aNome.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyNome() {
        if (!aNome.isNull()) {
            aNome.setNull(true);
            setModified(true);
        }
    }
    
    public DomText getNome() {
        return aNome;
    }
    
    public DomText oldNome() {
        return oNome;
    }
    
    public String valueOfNome() {
        return aNome.getValue();
    }
    
    public boolean isNomeModified() {
        return aNome.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo VAZAO_NOMINAL">
    
    public EntTipoModeloHidrometro vazaoNominal(Double value) {
        setVazaoNominal(value);
        return this;
    }
    
    public void setVazaoNominal(DomDouble value) {
        if (value == null || value.isNull()) {
            nullifyVazaoNominal();
        } else {
            aVazaoNominal.setValue(value.getValue());
            if (aVazaoNominal.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setVazaoNominal(String value) {
        if (value == null) {
            nullifyVazaoNominal();
        } else {
            aVazaoNominal.setValue(value);
            if (aVazaoNominal.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setVazaoNominal(Double value) {
        aVazaoNominal.setValue(value);
        if (aVazaoNominal.isModified()) {
            setModified(true);
        }
    }
    
    public void setVazaoNominal(Object value) {
        aVazaoNominal.setValue(value);
        if (aVazaoNominal.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyVazaoNominal() {
        if (!aVazaoNominal.isNull()) {
            aVazaoNominal.setNull(true);
            setModified(true);
        }
    }
    
    public DomDouble getVazaoNominal() {
        return aVazaoNominal;
    }
    
    public DomDouble oldVazaoNominal() {
        return oVazaoNominal;
    }
    
    public Double valueOfVazaoNominal() {
        return aVazaoNominal.getValue();
    }
    
    public boolean isVazaoNominalModified() {
        return aVazaoNominal.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo PREFIXO_NUMERO_SERIE">
    
    public EntTipoModeloHidrometro prefixoNumeroSerie(String value) {
        setPrefixoNumeroSerie(value);
        return this;
    }
    
    public void setPrefixoNumeroSerie(DomUpper value) {
        if (value == null || value.isNull()) {
            nullifyPrefixoNumeroSerie();
        } else {
            aPrefixoNumeroSerie.setValue(value.getValue());
            if (aPrefixoNumeroSerie.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setPrefixoNumeroSerie(String value) {
        if (value == null) {
            nullifyPrefixoNumeroSerie();
        } else {
            aPrefixoNumeroSerie.setValue(value);
            if (aPrefixoNumeroSerie.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setPrefixoNumeroSerie(Object value) {
        aPrefixoNumeroSerie.setValue(value);
        if (aPrefixoNumeroSerie.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyPrefixoNumeroSerie() {
        if (!aPrefixoNumeroSerie.isNull()) {
            aPrefixoNumeroSerie.setNull(true);
            setModified(true);
        }
    }
    
    public DomUpper getPrefixoNumeroSerie() {
        return aPrefixoNumeroSerie;
    }
    
    public DomUpper oldPrefixoNumeroSerie() {
        return oPrefixoNumeroSerie;
    }
    
    public String valueOfPrefixoNumeroSerie() {
        return aPrefixoNumeroSerie.getValue();
    }
    
    public boolean isPrefixoNumeroSerieModified() {
        return aPrefixoNumeroSerie.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo DESCRICAO">
    
    public EntTipoModeloHidrometro descricao(String value) {
        setDescricao(value);
        return this;
    }
    
    public void setDescricao(DomTextLong value) {
        if (value == null || value.isNull()) {
            nullifyDescricao();
        } else {
            aDescricao.setValue(value.getValue());
            if (aDescricao.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setDescricao(String value) {
        if (value == null) {
            nullifyDescricao();
        } else {
            aDescricao.setValue(value);
            if (aDescricao.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setDescricao(Object value) {
        aDescricao.setValue(value);
        if (aDescricao.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyDescricao() {
        if (!aDescricao.isNull()) {
            aDescricao.setNull(true);
            setModified(true);
        }
    }
    
    public DomTextLong getDescricao() {
        return aDescricao;
    }
    
    public DomTextLong oldDescricao() {
        return oDescricao;
    }
    
    public String valueOfDescricao() {
        return aDescricao.getValue();
    }
    
    public boolean isDescricaoModified() {
        return aDescricao.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo PREFIXO_MODELO">
    
    public EntTipoModeloHidrometro prefixoModelo(String value) {
        setPrefixoModelo(value);
        return this;
    }
    
    public void setPrefixoModelo(DomUpper value) {
        if (value == null || value.isNull()) {
            nullifyPrefixoModelo();
        } else {
            aPrefixoModelo.setValue(value.getValue());
            if (aPrefixoModelo.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setPrefixoModelo(String value) {
        if (value == null) {
            nullifyPrefixoModelo();
        } else {
            aPrefixoModelo.setValue(value);
            if (aPrefixoModelo.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setPrefixoModelo(Object value) {
        aPrefixoModelo.setValue(value);
        if (aPrefixoModelo.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyPrefixoModelo() {
        if (!aPrefixoModelo.isNull()) {
            aPrefixoModelo.setNull(true);
            setModified(true);
        }
    }
    
    public DomUpper getPrefixoModelo() {
        return aPrefixoModelo;
    }
    
    public DomUpper oldPrefixoModelo() {
        return oPrefixoModelo;
    }
    
    public String valueOfPrefixoModelo() {
        return aPrefixoModelo.getValue();
    }
    
    public boolean isPrefixoModeloModified() {
        return aPrefixoModelo.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo PROXIMA_SEQUENCIA_PRODUTO">
    
    public EntTipoModeloHidrometro proximaSequenciaProduto(Integer value) {
        setProximaSequenciaProduto(value);
        return this;
    }
    
    public void setProximaSequenciaProduto(DomInteger value) {
        if (value == null || value.isNull()) {
            nullifyProximaSequenciaProduto();
        } else {
            aProximaSequenciaProduto.setValue(value.getValue());
            if (aProximaSequenciaProduto.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setProximaSequenciaProduto(String value) {
        if (value == null) {
            nullifyProximaSequenciaProduto();
        } else {
            aProximaSequenciaProduto.setValue(value);
            if (aProximaSequenciaProduto.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setProximaSequenciaProduto(Integer value) {
        aProximaSequenciaProduto.setValue(value);
        if (aProximaSequenciaProduto.isModified()) {
            setModified(true);
        }
    }
    
    public void setProximaSequenciaProduto(Object value) {
        aProximaSequenciaProduto.setValue(value);
        if (aProximaSequenciaProduto.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyProximaSequenciaProduto() {
        if (!aProximaSequenciaProduto.isNull()) {
            aProximaSequenciaProduto.setNull(true);
            setModified(true);
        }
    }
    
    public DomInteger getProximaSequenciaProduto() {
        return aProximaSequenciaProduto;
    }
    
    public DomInteger oldProximaSequenciaProduto() {
        return oProximaSequenciaProduto;
    }
    
    public Integer valueOfProximaSequenciaProduto() {
        return aProximaSequenciaProduto.getValue();
    }
    
    public boolean isProximaSequenciaProdutoModified() {
        return aProximaSequenciaProduto.isModified();
    }
    // </editor-fold>
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="getErrors">
    /**
     * Traduz um erro recebido do banco de dados para um AdsException
     */
    @Override
    public AdsException getErrors(String errorMsg, int transaction) {
        AdsException e;
        String msg = errorMsg.toUpperCase();
        
        if (transaction == DELETE_TRANSACTION) {
            e = new AdsException("ZTEST.TIPO_MODELO_HIDROMETRO.GET_ERRORS_UNKNOWN",
                    AdsException.UNKNOWN,
                    "Erro não esperado: " + errorMsg);
        } else {
            if (msg.indexOf("VERIFICAR_SE_PODE_ALTERAR") >= 0) {
                e = new AdsException("ZTEST.TIPO_MODELO_HIDROMETRO.VERIFICAR_SE_PODE_ALTERAR", 
                        Severity.ERROR,
                        "Regra inválida! Plano de execução é sequencia de Planos de execuções (VERIFICAR_SE_PODE_ALTERAR)");
                return e;
            } else if (msg.indexOf("UK_TIPMOD_CODIGO") >= 0) {
                e = new AdsException("ZTEST.TIPO_MODELO_HIDROMETRO.UK_TIPMOD_CODIGO", 
                        Severity.ERROR,
                        "Registro duplicado! Código do tipo do modelo de hidrômetro deve ser único Código do tipo de modelo ${CODIGO} (UK_TIPMOD_CODIGO)");
                return e;
            } else if (msg.indexOf("PK_TIPMOD") >= 0) {
                e = new AdsException("ZTEST.TIPO_MODELO_HIDROMETRO.PK_TIPMOD", 
                        Severity.ERROR,
                        "ID duplicado! (PK_TIPMOD)");
                return e;
            } else {
                e = new AdsException("ZTEST.TIPO_MODELO_HIDROMETRO.GET_ERRORS_UNKNOWN",
                        AdsException.UNKNOWN,
                        "Erro não esperado: " + errorMsg);
            }
        }
        return e;
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Entity Information">
    
    public String getEntityName() {
        return ENTITY_NAME;
    }
    
    public String getTableName() {
        return TABLE_NAME;
    }
    
    public String idSequenceName() {
        return "PK_SEQUENCE";
    }
    
    private ArrayList<Field> allAttributes;
    public ArrayList<Field> getAllAttributes() {
        if (allAttributes == null) {
            allAttributes = new ArrayList<Field>();
            allAttributes.add(aId);
            allAttributes.add(aCodigo);
            allAttributes.add(aNome);
            allAttributes.add(aVazaoNominal);
            allAttributes.add(aPrefixoNumeroSerie);
            allAttributes.add(aDescricao);
            allAttributes.add(aPrefixoModelo);
            allAttributes.add(aProximaSequenciaProduto);
        }
        return allAttributes;
    }
    
    /**
     * Retorna o valor da primeira UK da entidade
     * Se ela for composta, retorna a concatenação de toda a combinação
     * de atributos separados por um espaço.
     */
    public String valueOfUk() {
        return getCodigo().toString();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Relationships">
    
    
    public void findByCodigo(String codigo) throws AdsException {
        findBy(new String[] {"CODIGO"},
                new Object[] {codigo});
    }
    
    /**
     * Método que copia os valores dos atributos
     * para os valores respectivos old 
     */
    public void saveOldAtributes() {
        oCodigo.setValue(aCodigo);
        oVazaoNominal.setValue(aVazaoNominal);
        oProximaSequenciaProduto.setValue(aProximaSequenciaProduto);
        oPrefixoModelo.setValue(aPrefixoModelo);
        oDescricao.setValue(aDescricao);
        oPrefixoNumeroSerie.setValue(aPrefixoNumeroSerie);
        oNome.setValue(aNome);
        oId.setValue(aId);
    }
    
    /**
     * Método que retorna as regras da entidade
     * @return ArrayList com as regras ou null caso não existir nenhuma regra
     */
    public ArrayList getAllRules() {
        ArrayList<EntityRule> out = new ArrayList<EntityRule>();
        {
            PrimaryKeyRule rule = new PrimaryKeyRule();
            rule.setEntity(EntTipoModeloHidrometro.class);
            rule.setName("PK_TIPMOD");
            rule.setPkAttribute(new DomId("ID",""));
            out.add(rule);
        }
        {
            UniqueKeyRule rule = new UniqueKeyRule();
            rule.setEntity(EntTipoModeloHidrometro.class);
            rule.setName("UK_TIPMOD_CODIGO");
            rule.addAttribute(new DomText("CODIGO",""));
            out.add(rule);
        }
        return out;
    }
    // </editor-fold>
    
    @Override
    protected void preInsert() throws AdsException {
        calcularOCodigoTipo(); //Calcular o código do tipo
    }
    
    @Override
    protected void preUpdate() throws AdsException {
        calcularOCodigoTipo(); //Calcular o código do tipo
        checkRule(isVerificarSePodeAlterarValid(), "VERIFICAR_SE_PODE_ALTERAR", "Plano de execução é sequencia de Planos de execuções");
    }
    
    @Override
    public void fillDefaultValues() throws AdsException {
        if (aId.isNull()) {
            aId.setValue("" + ctx.getNextVal("pk_sequence"));
        }
        if (getProximaSequenciaProduto().isNull()) {
            setProximaSequenciaProduto(getProximaSequenciaProduto().getDefaultValue());
        }
    }
    
    // <editor-fold defaultstate="collapsed" desc="Métodos customizados">
    
    /**
     * Regra de validação: Plano de execução é sequencia de Planos de execuções
     */
    private Object isVerificarSePodeAlterarValid() throws AdsException {
        // <user-code id="20650005" parentId="20649999" hashcode="-13c69d0c" length="1144">
        int qtdeRegistros = ctx.computeSqlInteger(
                "select count(qry.qtde)"
                + " from ("
                + " select count(sole.id) as qtde"
                + " from modelo_hidrometro mdlh"
                + " join solicitacao_ensaio sole on sole.modelo_hidrometro_id = mdlh.id"
                + " left join hidrometro hidm on hidm.modelo_hidrometro_id = mdlh.id"
                + " where mdlh.tipo_modelo_hidrometro_id = (select id from tipo_modelo_hidrometro where id = ?)"
                + " union" 
                + " select count(hidm.id) as qtde"
                + " from modelo_hidrometro mdlh" 
                + " join hidrometro hidm on hidm.modelo_hidrometro_id = mdlh.id"
                + " where mdlh.tipo_modelo_hidrometro_id = (select id from tipo_modelo_hidrometro where id = ?)"
                + " ) qry",
                0,
                valueOfId(), 
                valueOfId()
                );
        
        if (qtdeRegistros > 0) {
            ctx.pushError(ENTITY_NAME,
                    Severity.WARNING,
                    "Já existe solicitações de ensaio e/ou hidrômetros cadastrados com modelos deste tipo!"
                    + " Alteração dos dados para este tipo não é permitida.");
        }
        
        return (ctx.hasErrors() || ctx.hasWarnings());
        // </user-code>
    }
    
    /**
     * Regra de ação: Calcular o código do tipo
     */
    private void calcularOCodigoTipo() throws AdsException {
        // <user-code id="21794434" parentId="21794347" hashcode="51b835ad" length="208">
        if (isNomeModified() || isPrefixoModeloModified() || isVazaoNominalModified()) {
            setCodigo(valueOfNome() 
                    + " " + valueOfPrefixoModelo() 
                    + " " + getVazaoNominal().toText());
        }
        // </user-code>
    }
}
